{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "<a href=\"https://colab.research.google.com/drive/1PauKcACsbHUyC3Gx_HY2CR4rDC_tXZsw?usp=sharing\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
        "\n",
        "### 🔗 Prompt Chaining - Prompt Engineering\n",
        "\n",
        "Prompt Chaining is a method of breaking down complex tasks into a series of simpler, interconnected prompts.\n",
        "\n",
        "### Key points:\n",
        "\n",
        "* 🔑 **Core concept:** Use the output of one prompt as input for the next in a sequence.\n",
        "\n",
        "* ⚙️ **Process:**\n",
        "  * Divide the main task into smaller, manageable sub-tasks\n",
        "  * Create a series of prompts, each addressing a sub-task\n",
        "  * Pass results from each step to inform subsequent prompts\n",
        "\n",
        "* 🌟 **Advantages:**\n",
        "  * Handles complex, multi-stage problems more effectively\n",
        "  * Improves overall task performance and accuracy\n",
        "\n",
        "* 💼 **Applications:** Data analysis, content creation, multi-step reasoning tasks.\n",
        "\n",
        "* 🚀**Implementation:**\n",
        "  * Design a logical sequence of prompts\n",
        "  * Ensure each prompt builds on previous results\n",
        "  * Manage context and token limits across the chain\n",
        "\n",
        "* ⚖️ **Challenges:**\n",
        "  * Error propagation through the chain\n",
        "  * Maintaining coherence across multiple prompts\n",
        "\n",
        "* 📝 **Example structure:**\n",
        "  * Step 1: [Initial prompt]\n",
        "  * Step 2: Given [result from Step 1], now [next sub-task]\n",
        "  * Step 3: Using [results from Steps 1 and 2], [final sub-task]\n",
        "\n",
        "* 🔄 **Variations:** Can be combined with other techniques like CoT or ReAct for enhanced performance."
      ],
      "metadata": {
        "id": "Y2eqHW0TK87s"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "!pip install -q -U langchain-groq==0.2.4"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "KI4D1HL-LKaP",
        "outputId": "d4451490-67d2-4a1f-c2ce-831c1cc155fb"
      },
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/121.9 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m121.9/121.9 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain_groq import ChatGroq\n",
        "from langchain.prompts import ChatPromptTemplate"
      ],
      "metadata": {
        "id": "dfHHptAFLMwj"
      },
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "import getpass"
      ],
      "metadata": {
        "id": "eZJGDTIMLOnP"
      },
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### 🔑 Provide Groq API Key\n",
        "\n",
        "- [Groq API Key](https://console.groq.com/keys)\n",
        "\n"
      ],
      "metadata": {
        "id": "rQrlkg_bLRZp"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "os.environ[\"GROQ_API_KEY\"] = getpass.getpass()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "XI8sLK8uLTht",
        "outputId": "c181cc76-ce90-4671-bf39-6035706b2253"
      },
      "execution_count": 4,
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "··········\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "llm = ChatGroq(\n",
        "    model=\"llama3-8b-8192\",\n",
        "    temperature=0.5\n",
        ")"
      ],
      "metadata": {
        "id": "0os_AIehLVh1"
      },
      "execution_count": 5,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def prompt_chaining(topic):\n",
        "    overview_prompt = ChatPromptTemplate.from_messages(\n",
        "        [\n",
        "          (\"system\", \"You are an AI that can generate brief overviews of topics.\"),\n",
        "          (\"human\", \"Generate a brief overview of {topic}:\"),\n",
        "        ]\n",
        "    )\n",
        "\n",
        "    topic_chain = overview_prompt | llm\n",
        "    overview = topic_chain.invoke({\"topic\": topic}).content\n",
        "\n",
        "    key_points_prompt = ChatPromptTemplate.from_messages(\n",
        "        [\n",
        "          (\"system\", \"You are an AI that can extract key points from overviews.\"),\n",
        "          (\"human\", \"\"\"Based on this overview, list 3 key points:\n",
        "            {overview}\n",
        "            Key points:\"\"\"),\n",
        "        ]\n",
        "    )\n",
        "\n",
        "    overview_chain = key_points_prompt | llm\n",
        "    response = overview_chain.invoke({\"overview\": overview}).content\n",
        "\n",
        "    return response"
      ],
      "metadata": {
        "id": "FToKQB7jLBYD"
      },
      "execution_count": 6,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "topic = \"quantum computing\"\n",
        "response = prompt_chaining(topic)\n",
        "print(response)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0PWEvnMyLZSb",
        "outputId": "c5e01645-0656-49fe-f5c5-2c4589ad2ebc"
      },
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Here are 3 key points extracted from the overview:\n",
            "\n",
            "1. **Unique processing power**: Quantum computers use qubits, which can exist in multiple states simultaneously, allowing for the processing of vast amounts of data in parallel, unlike classical computers which use bits (0s and 1s).\n",
            "\n",
            "2. **Potential applications**: Quantum computers have the potential to solve complex problems that are currently unsolvable with classical computers, such as simulating complex systems, breaking complex encryption codes, and optimizing complex systems.\n",
            "\n",
            "3. **Challenges and advancements**: Developing practical quantum computers faces challenges such as maintaining qubit states, scaling up qubits, and developing software and applications, but significant advancements have been made in recent years, with several companies and organizations actively working on developing practical quantum computers.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "ja7ZCUY2MJT2"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}